#define _UARTAPP_GLOBAL_
#include "config.h"

void Uart1DeInit(void)
{
	Uart1_RxEn = 0;
	Uart1_TxEn = 0;

	DMA_DeInit(DMA1_Channel5);
	/* Enable the USART1 Interrupt */
	NVIC_Configuration(USART1_IRQn,USART1_PREPRIORITY,USART1_SUBPRIORITY,DISABLE);

	USART_DeInit(USART1);

	/* Configure USART1 Tx (PA.09) as input floating */
	GPIOA_MODE9=INPUT_MODE;GPIOA_CNF9=IN_FLOATING;
	/* Configure USART1 Rx (PA.10) as input floating */
	GPIOA_MODE10=INPUT_MODE;GPIOA_CNF10=IN_FLOATING;
}

u8 UART1_Rxdata[Uart1RxFifoSize];
u16 uart1HaveRxCnt;

void Uart1Init(u32 baudrate)
{
	USART_InitTypeDef USART_InitStructure;
//	USART_ClockInitTypeDef USART_ClockinitStructure;

///////////////////////DMA
  	DMA_InitTypeDef DMA_InitStructure;
///////////////////////DMA

	GPIOA_MODE9=OUTPUT_MODE_50MHZ;GPIOA_CNF9=OUT_AL_PP;
	/* Configure USART1 Rx (PA.10) as input floating */
	GPIOA_MODE10=INPUT_MODE;GPIOA_CNF10=IN_PP;
	GPIOA_SET=(1<<10);

//	GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);

	FIFO_INIT(Uart1RxFifo);	
	FIFO_INIT(Uart1TxFifo);	
	/* Enable USART1 clocks */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	/* Enable the USART1 Interrupt */
	NVIC_Configuration(USART1_IRQn,USART1_PREPRIORITY,USART1_SUBPRIORITY,ENABLE);

///////////////////////DMA
  /* USARTy TX DMA1 Channel (triggered by USARTy Rx event) Config */
  DMA_DeInit(DMA1_Channel5);  
  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UART1_Rxdata;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = Uart1RxFifoSize;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel5, &DMA_InitStructure);
///////////////////////DMA

	/* USART1 configuration ------------------------------------------------------*/
	/* USART1 configured as follow:
        - BaudRate = 9600 baud  
        - Word Length = 8 Bits
        - Two Stop Bit
        - Odd parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
        - USART Clock disabled
        - USART CPOL: Clock is active low
        - USART CPHA: Data is captured on the second edge 
        - USART LastBit: The clock pulse of the last data bit is not output to 
                         the SCLK pin
	*/
	USART_InitStructure.USART_BaudRate = baudrate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	/* Configure the USART1 */
	USART_Init(USART1, &USART_InitStructure);
/*
	USART_ClockinitStructure.USART_Clock = USART_Clock_Disable;
	USART_ClockinitStructure.USART_CPOL = USART_CPOL_Low;
	USART_ClockinitStructure.USART_CPHA = USART_CPHA_2Edge;
	USART_ClockinitStructure.USART_LastBit = USART_LastBit_Disable;
	USART_ClockInit(USART1, &USART_ClockinitStructure);
*/
///////////////////////DMA
  USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
  DMA_Cmd(DMA1_Channel5, ENABLE);
  uart1HaveRxCnt = 0;
///////////////////////DMA
	/* Enable the USART Transmoit interrupt: this interrupt is generated when the 
	USART1 transmit data register is empty */  
//	USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

	/* Enable the USART Receive interrupt: this interrupt is generated when the 
	USART1 receive data register is not empty */
//	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

	/* Enable USART1 */
	USART_Cmd(USART1, ENABLE);
///////////////////////DMA
  DMA_Cmd(DMA1_Channel5, ENABLE);
///////////////////////DMA
	Uart1_RxEn = 1;
	Uart1_TxEn = 1;
}

void ReadUart1DataUsingDMA(void)
{
	u16	nowHave;
	if (Uart1_RxEn)
	{
		nowHave = Uart1RxFifoSize - DMA_GetCurrDataCounter(DMA1_Channel5);
		if(nowHave >= Uart1RxFifoSize)
		{
			return;
		}
		if(nowHave != uart1HaveRxCnt)
		{
			while(nowHave != uart1HaveRxCnt)
			{
				FIFO_PUT_ONE(Uart1RxFifo,UART1_Rxdata[uart1HaveRxCnt]);
				uart1HaveRxCnt++;
				if(uart1HaveRxCnt == Uart1RxFifoSize)
				{
					uart1HaveRxCnt = 0; 
				}
			}
		}
	}
}
void Uart2DeInit(void)
{
	Uart2_RxEn = 0;
	Uart2_TxEn = 0;
	DMA_DeInit(DMA1_Channel6);
	/* Enable the USART2 Interrupt */
	NVIC_Configuration(USART2_IRQn,USART2_PREPRIORITY,USART2_SUBPRIORITY,DISABLE);

	USART_DeInit(USART2);

#if 1
	GPIOA_MODE3=INPUT_MODE;GPIOA_CNF3=IN_FLOATING;
	GPIOA_MODE2=INPUT_MODE;GPIOA_CNF2=IN_FLOATING;
#else
	/* Configure USART2 Tx (PD.05) as input floating */
	GPIOD_MODE5=INPUT_MODE;GPIOD_CNF5=IN_FLOATING;
	/* Configure USART2 Rx (PD.06) as input floating */
	GPIOD_MODE6=INPUT_MODE;GPIOD_CNF6=IN_FLOATING;
#endif
}

u8 UART2_Rxdata[Uart2RxFifoSize];
u16 uart2HaveRxCnt;

void Uart2Init(u32 baudrate)
{
	USART_InitTypeDef USART_InitStructure;
//	USART_ClockInitTypeDef USART_ClockinitStructure;

///////////////////////DMA
  DMA_InitTypeDef DMA_InitStructure;
///////////////////////DMA

#if 1
	GPIOA_MODE2=OUTPUT_MODE_50MHZ;GPIOA_CNF2=OUT_AL_PP;
	GPIOA_MODE3=INPUT_MODE;GPIOA_CNF3=IN_FLOATING;
#else
	/* Configure USART2 Tx (PD.05) as alternate function push-pull */
	GPIOD_MODE5=OUTPUT_MODE_50MHZ;GPIOD_CNF5=OUT_AL_PP;
	/* Configure USART2 Rx (PD.06) as input floating */
	GPIOD_MODE6=INPUT_MODE;GPIOD_CNF6=IN_FLOATING;

	GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);
#endif

	FIFO_INIT(Uart2RxFifo);	
	FIFO_INIT(Uart2TxFifo);	
	/* Enable USART2 clocks */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

	/* Enable the USART2 Interrupt */
	NVIC_Configuration(USART2_IRQn,USART2_PREPRIORITY,USART2_SUBPRIORITY,ENABLE);

///////////////////////DMA
  /* USARTy TX DMA1 Channel (triggered by USARTy Rx event) Config */
  DMA_DeInit(DMA1_Channel6);  
  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UART2_Rxdata;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = Uart2RxFifoSize;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel6, &DMA_InitStructure);
///////////////////////DMA

	/* USART1 configuration ------------------------------------------------------*/
	/* USART1 configured as follow:
        - BaudRate = 9600 baud  
        - Word Length = 8 Bits
        - Two Stop Bit
        - Odd parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
        - USART Clock disabled
        - USART CPOL: Clock is active low
        - USART CPHA: Data is captured on the second edge 
        - USART LastBit: The clock pulse of the last data bit is not output to 
                         the SCLK pin
	*/
	USART_InitStructure.USART_BaudRate = baudrate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	/* Configure the USART2 */
	USART_Init(USART2, &USART_InitStructure);

//	USART_ClockinitStructure.USART_Clock = USART_Clock_Disable;
//	USART_ClockinitStructure.USART_CPOL = USART_CPOL_Low;
//	USART_ClockinitStructure.USART_CPHA = USART_CPHA_2Edge;
//	USART_ClockinitStructure.USART_LastBit = USART_LastBit_Disable;
//	/* Configure the USART2 */
//	USART_ClockInit(USART2, &USART_ClockinitStructure);
///////////////////////DMA
  USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
  DMA_Cmd(DMA1_Channel6, ENABLE);
  uart2HaveRxCnt = 0;
///////////////////////DMA
	/* Enable the USART Transmoit interrupt: this interrupt is generated when the 
	USART2 transmit data register is empty */  
//	USART_ITConfig(USART2, USART_IT_TXE, ENABLE);

	/* Enable the USART Receive interrupt: this interrupt is generated when the 
	USART2 receive data register is not empty */
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

	/* Enable USART2 */
	USART_Cmd(USART2, ENABLE);
///////////////////////DMA
  DMA_Cmd(DMA1_Channel6, ENABLE);
///////////////////////DMA
	Uart2_RxEn = 1;
	Uart2_TxEn = 1;
}

void ReadUart2DataUsingDMA(void)
{
	u16	nowHave;
	if (Uart2_RxEn)
	{
		nowHave = Uart2RxFifoSize - DMA_GetCurrDataCounter(DMA1_Channel6);
		if(nowHave >= Uart2RxFifoSize)
		{
			return;
		}
		if(nowHave != uart2HaveRxCnt)
		{
			while(nowHave != uart2HaveRxCnt)
			{
				FIFO_PUT_ONE(Uart2RxFifo,UART2_Rxdata[uart2HaveRxCnt]);
				uart2HaveRxCnt++;
				if(uart2HaveRxCnt == Uart2RxFifoSize)
				{
					uart2HaveRxCnt = 0; 
				}
			}
		}
	}
}

void Uart3DeInit(void)
{
	DMA_DeInit(DMA1_Channel3);
	/* Enable the USART3 Interrupt */
	NVIC_Configuration(USART3_IRQn,USART3_PREPRIORITY,USART3_SUBPRIORITY,DISABLE);

	USART_DeInit(USART3);

#if 1
	GPIOB_MODE10=INPUT_MODE;GPIOB_CNF10=IN_FLOATING;
	GPIOB_MODE11=INPUT_MODE;GPIOB_CNF11=IN_FLOATING;
#else
	/* Configure USART3 Tx (PD.08) as input floating */
	GPIOD_MODE8=INPUT_MODE;GPIOD_CNF8=IN_FLOATING;
	/* Configure USART3 Rx (PD.09) as input floating */
	GPIOD_MODE9=INPUT_MODE;GPIOD_CNF9=IN_FLOATING;
#endif
}

u8 UART3_Rxdata[Uart3RxFifoSize];
u16 uart3HaveRxCnt;

void Uart3Init(u32 baudrate)
{
	USART_InitTypeDef USART_InitStructure;
//	USART_ClockInitTypeDef USART_ClockinitStructure;

///////////////////////DMA
  DMA_InitTypeDef DMA_InitStructure;
///////////////////////DMA

#if 1
	GPIOB_MODE10=OUTPUT_MODE_50MHZ;GPIOB_CNF10=OUT_AL_PP;
	GPIOB_MODE11=INPUT_MODE;GPIOB_CNF11=IN_FLOATING;
#else
	/* Configure USART3 Tx (PD.08) as alternate function push-pull */
	GPIOD_MODE8=OUTPUT_MODE_50MHZ;GPIOD_CNF8=OUT_AL_PP;
	/* Configure UART1 Rx (PD.09) as input floating */
	GPIOD_MODE9=INPUT_MODE;GPIOD_CNF9=IN_FLOATING;

	GPIO_PinRemapConfig(GPIO_FullRemap_USART3,ENABLE);
#endif

	FIFO_INIT(Uart3RxFifo);	
	FIFO_INIT(Uart3TxFifo);	
	/* Enable USART3 clocks */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

	/* Enable the USART3 Interrupt */
	NVIC_Configuration(USART3_IRQn,USART3_PREPRIORITY,USART3_SUBPRIORITY,ENABLE);
	/* USART1 configuration ------------------------------------------------------*/
	/* USART1 configured as follow:
        - BaudRate = 9600 baud  
        - Word Length = 8 Bits
        - Two Stop Bit
        - Odd parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
        - USART Clock disabled
        - USART CPOL: Clock is active low
        - USART CPHA: Data is captured on the second edge 
        - USART LastBit: The clock pulse of the last data bit is not output to 
                         the SCLK pin
	*/
	USART_InitStructure.USART_BaudRate = baudrate;
	USART_InitStructure.USART_WordLength = USART_WordLength_9b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_Even;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	/* Configure the USART3 */
	USART_Init(USART3, &USART_InitStructure);

///////////////////////DMA
  /* USARTy TX DMA1 Channel (triggered by USARTy Rx event) Config */
  DMA_DeInit(DMA1_Channel3);  
  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004804;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UART3_Rxdata;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = Uart3RxFifoSize;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel3, &DMA_InitStructure);
///////////////////////DMA

/*
	USART_ClockinitStructure.USART_Clock = USART_Clock_Disable;
	USART_ClockinitStructure.USART_CPOL = USART_CPOL_Low;
	USART_ClockinitStructure.USART_CPHA = USART_CPHA_2Edge;
	USART_ClockinitStructure.USART_LastBit = USART_LastBit_Disable;
	USART_ClockInit(USART3, &USART_ClockinitStructure);
*/
///////////////////////DMA
  USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
  DMA_Cmd(DMA1_Channel3, ENABLE);
  uart3HaveRxCnt = 0;
///////////////////////DMA
	/* Enable the USART Transmoit interrupt: this interrupt is generated when the 
	USART3 transmit data register is empty */  
//	USART_ITConfig(USART3, USART_IT_TXE, ENABLE);

	/* Enable the USART Receive interrupt: this interrupt is generated when the 
	USART3 receive data register is not empty */
//	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

	/* Enable USART3 */
	USART_Cmd(USART3, ENABLE);
	Uart3_RxEn = 1;
	Uart3_TxEn = 1;
///////////////////////DMA
  DMA_Cmd(DMA1_Channel3, ENABLE);
///////////////////////DMA
}

void ReadUart3DataUsingDMA(void)
{
	u16	nowHave;
	if (Uart3_RxEn)
	{
		nowHave = Uart3RxFifoSize - DMA_GetCurrDataCounter(DMA1_Channel3);
		if(nowHave >= Uart3RxFifoSize)
		{
			return;
		}
		if(nowHave != uart3HaveRxCnt)
		{
			while(nowHave != uart3HaveRxCnt)
			{
				FIFO_PUT_ONE(Uart3RxFifo,UART3_Rxdata[uart3HaveRxCnt]);
				uart3HaveRxCnt++;
				if(uart3HaveRxCnt == Uart3RxFifoSize)
				{
					uart3HaveRxCnt = 0; 
				}
			}
		}
	}
}

void Uart4DeInit(void)
{
	DMA_DeInit(DMA2_Channel3);
	/* Enable the UART5 Interrupt */
	NVIC_Configuration(UART4_IRQn,UART4_PREPRIORITY,UART4_SUBPRIORITY,DISABLE);

	USART_DeInit(UART4);

	/* Configure UART5 Tx (PC.10) as input floating */
	GPIOC_MODE10=INPUT_MODE;GPIOC_CNF10=IN_FLOATING;
	/* Configure UART5 Rx (PC.11) as input floating */
	GPIOC_MODE11=INPUT_MODE;GPIOC_CNF11=IN_FLOATING;
}

u8 UART4_Rxdata[Uart4RxFifoSize];
u16 uart4HaveRxCnt;

void Uart4Init(u32 baudrate)
{
	USART_InitTypeDef USART_InitStructure;
//	USART_ClockInitTypeDef USART_ClockinitStructure;

///////////////////////DMA
  DMA_InitTypeDef DMA_InitStructure;
///////////////////////DMA

	GPIOC_MODE10=OUTPUT_MODE_50MHZ;GPIOC_CNF10=OUT_AL_PP;
	/* Configure USART3 Rx (PD.09) as input floating */
	GPIOC_MODE11=INPUT_MODE;GPIOC_CNF11=IN_FLOATING;

	FIFO_INIT(Uart4RxFifo);	
	FIFO_INIT(Uart4TxFifo);	
	/* Enable UART4 clocks */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);



	/* Enable the UART5 Interrupt */
	NVIC_Configuration(UART4_IRQn,UART4_PREPRIORITY,UART4_SUBPRIORITY,ENABLE);
	/* USART4 configuration ------------------------------------------------------*/
	/* USART4 configured as follow:
        - BaudRate = 9600 baud  
        - Word Length = 8 Bits
        - Two Stop Bit
        - Odd parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
        - USART Clock disabled
        - USART CPOL: Clock is active low
        - USART CPHA: Data is captured on the second edge 
        - USART LastBit: The clock pulse of the last data bit is not output to 
                         the SCLK pin
	*/
	USART_InitStructure.USART_BaudRate = baudrate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	/* Configure the UART4 */
	USART_Init(UART4, &USART_InitStructure);

///////////////////////DMA
  /* USARTy TX DMA2 Channel (triggered by USARTy Rx event) Config */
  DMA_DeInit(DMA2_Channel3);  
  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004C04;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UART4_Rxdata;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = Uart4RxFifoSize;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA2_Channel3, &DMA_InitStructure);
///////////////////////DMA
/*
	USART_ClockinitStructure.USART_Clock = USART_Clock_Disable;
	USART_ClockinitStructure.USART_CPOL = USART_CPOL_Low;
	USART_ClockinitStructure.USART_CPHA = USART_CPHA_2Edge;
	USART_ClockinitStructure.USART_LastBit = USART_LastBit_Disable;
	USART_ClockInit(UART4, &USART_ClockinitStructure);
*/
///////////////////////DMA
  USART_DMACmd(UART4, USART_DMAReq_Rx, ENABLE);
  DMA_Cmd(DMA2_Channel3, ENABLE);
  uart4HaveRxCnt = 0;
///////////////////////DMA
	/* Enable the UART Transmoit interrupt: this interrupt is generated when the 
	USART1 transmit data register is empty */  
//	USART_ITConfig(UART4, USART_IT_TXE, ENABLE);

	/* Enable the USART Receive interrupt: this interrupt is generated when the 
	USART1 receive data register is not empty */
//	USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);

	/* Enable USART4 */
	USART_Cmd(UART4, ENABLE);
	Uart4_RxEn = 1;
	Uart4_TxEn = 1;
///////////////////////DMA
  DMA_Cmd(DMA2_Channel3, ENABLE);
///////////////////////DMA
}

void ReadUart4DataUsingDMA(void)
{
	u16	nowHave;
	nowHave = Uart4RxFifoSize - DMA_GetCurrDataCounter(DMA2_Channel3);
	if(nowHave >= Uart4RxFifoSize)
	{
		return;
	}
	if(nowHave != uart4HaveRxCnt)
	{
		while(nowHave != uart4HaveRxCnt)
		{
			FIFO_PUT_ONE(Uart4RxFifo,UART4_Rxdata[uart4HaveRxCnt]);
			uart4HaveRxCnt++;
			if(uart4HaveRxCnt == Uart4RxFifoSize)
			{
				uart4HaveRxCnt = 0;	
			}
		}
	}
}

void Uart5DeInit(void)
{
	/* Enable the UART5 Interrupt */
	NVIC_Configuration(UART5_IRQn,UART5_PREPRIORITY,UART5_SUBPRIORITY,DISABLE);

	USART_DeInit(UART5);

	/* Configure UART5 Tx (PC.12) as input floating */
	GPIOC_MODE12=INPUT_MODE;GPIOC_CNF12=IN_FLOATING;
	/* Configure UART5 Rx (PD.2) as input floating */
	GPIOD_MODE2=INPUT_MODE;GPIOD_CNF2=IN_FLOATING;
}

void Uart5Init(u32 baudrate)
{
	USART_InitTypeDef USART_InitStructure;
//	USART_ClockInitTypeDef USART_ClockinitStructure;

	/* Configure UART1 Tx (PC.12) as alternate function push-pull */
	GPIOC_MODE12=OUTPUT_MODE_50MHZ;GPIOC_CNF12=OUT_AL_PP;
	/* Configure UART1 Rx (PD.2) as input floating */
	GPIOD_MODE2=INPUT_MODE;GPIOD_CNF2=IN_FLOATING;

	FIFO_INIT(Uart5RxFifo);	
	FIFO_INIT(Uart5TxFifo);	
	/* Enable UART5 clocks */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);

	/* Enable the UART5 Interrupt */
	NVIC_Configuration(UART5_IRQn,UART5_PREPRIORITY,UART5_SUBPRIORITY,ENABLE);
	/* USART1 configuration ------------------------------------------------------*/
	/* USART1 configured as follow:
        - BaudRate = 9600 baud  
        - Word Length = 8 Bits
        - Two Stop Bit
        - Odd parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
        - USART Clock disabled
        - USART CPOL: Clock is active low
        - USART CPHA: Data is captured on the second edge 
        - USART LastBit: The clock pulse of the last data bit is not output to 
                         the SCLK pin
	*/
	USART_InitStructure.USART_BaudRate = baudrate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	/* Configure the UART5 */
	USART_Init(UART5, &USART_InitStructure);

//	USART_ClockinitStructure.USART_Clock = USART_Clock_Disable;
//	USART_ClockinitStructure.USART_CPOL = USART_CPOL_Low;
//	USART_ClockinitStructure.USART_CPHA = USART_CPHA_2Edge;
//	USART_ClockinitStructure.USART_LastBit = USART_LastBit_Disable;
//	/* Configure the UART5 */
//	USART_ClockInit(UART5, &USART_ClockinitStructure);

	/* Enable the UART Transmoit interrupt: this interrupt is generated when the 
	USART1 transmit data register is empty */  
//	USART_ITConfig(UART5, USART_IT_TXE, ENABLE);

	/* Enable the USART Receive interrupt: this interrupt is generated when the 
	USART1 receive data register is not empty */
	USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);

	/* Enable USART1 */
	USART_Cmd(UART5, ENABLE);
	Uart5_RxEn = 1;
	Uart5_TxEn = 1;
}

void UARTRxFreeIdleProc(void)
{
	ReadUart1DataUsingDMA();
	ReadUart2DataUsingDMA();
	ReadUart3DataUsingDMA();
	ReadUart4DataUsingDMA();
}
void UARTTxFreeIdleProc(void)
{
	if(Uart1_TxEn > 0)
	{
		if(FIFO_GET_COUNT(Uart1TxFifo))//if TxBUFR is not EMPTY
		{
			/* Disable the USART1 Transmit interrupt */
			USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
		}
	}
	if(Uart2_TxEn > 0)
	{
		if(FIFO_GET_COUNT(Uart2TxFifo))//if TxBUFR is not EMPTY
		{
			/* Disable the USART2 Transmit interrupt */
			USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
		}
	}
	if(Uart3_TxEn > 0)
	{
		if(FIFO_GET_COUNT(Uart3TxFifo))//if TxBUFR is not EMPTY
		{
			/* Disable the USART3 Transmit interrupt */
			USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
		}
	}
	if(Uart4_TxEn > 0)
	{
		if(FIFO_GET_COUNT(Uart4TxFifo))//if TxBUFR is not EMPTY
		{
			/* Disable the USART4 Transmit interrupt */
			USART_ITConfig(UART4, USART_IT_TXE, ENABLE);
		}
	}
	if(Uart5_TxEn > 0)
	{
		if(FIFO_GET_COUNT(Uart5TxFifo))//if TxBUFR is not EMPTY
		{
			/* Disable the USART5 Transmit interrupt */
			USART_ITConfig(UART5, USART_IT_TXE, ENABLE);
		}
	}
}

/*
void USARTxPrintf(USART_TypeDef *USARTx,u8 *buff)
{
	uint16 usart;
	if (USARTx == USART1) usart = 1;
	else if (USARTx == USART2) usart = 2; 
	else if (USARTx == USART3) usart = 3;
	else if (USARTx == UART4) usart = 4; 
	else usart = 5; 
	while (*buff) {
		switch(usart) {
			case 1:
				FIFO_PUT_ONE(Uart1TxFifo,*buff);
				break;
			case 2:
				FIFO_PUT_ONE(Uart2TxFifo,*buff);
				break;
			case 3:
				FIFO_PUT_ONE(Uart3TxFifo,*buff);
				break;
			case 4:
				FIFO_PUT_ONE(Uart4TxFifo,*buff);
				break;
			case 5:
				FIFO_PUT_ONE(Uart5TxFifo,*buff);
				break; 
		}
		buff ++;
	}
}

void USARTxSendByte(USART_TypeDef *USARTx,u8 data)
{
	uint16 usart;
	if (USARTx == USART1) usart = 1;
	else if (USARTx == USART2) usart = 2; 
	else if (USARTx == USART3) usart = 3;
	else if (USARTx == UART4) usart = 4; 
	else usart = 5; 
		switch(usart) {
			case 1:
				FIFO_PUT_ONE(Uart1TxFifo,data);
				break;
			case 2:
				FIFO_PUT_ONE(Uart2TxFifo,data);
				break;
			case 3:
				FIFO_PUT_ONE(Uart3TxFifo,data);
				break;
			case 4:
				FIFO_PUT_ONE(Uart4TxFifo,data);
				break;
			case 5:
				FIFO_PUT_ONE(Uart5TxFifo,data);
				break;
		}
}

void USARTxSendNByte(USART_TypeDef *USARTx,u8 *pdata,u16 len)
{
	uint16 usart;
	if (USARTx == USART1) usart = 1;
	else if (USARTx == USART2) usart = 2; 
	else if (USARTx == USART3) usart = 3;
	else if (USARTx == UART4) usart = 4; 
	else usart = 5; 
	while (len > 0) {
		switch(usart) {
			case 1:
				FIFO_PUT_ONE(Uart1TxFifo,*pdata);
				break;
			case 2:
				FIFO_PUT_ONE(Uart2TxFifo,*pdata);
				break;
			case 3:
				FIFO_PUT_ONE(Uart3TxFifo,*pdata);
				break;
			case 4:
				FIFO_PUT_ONE(Uart4TxFifo,*pdata);
				break;
			case 5:
				FIFO_PUT_ONE(Uart5TxFifo,*pdata);
				break;
		}
		len --;
		pdata++;
	}
}

char HexTAB[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
void USARTxSendByteHex(USART_TypeDef *USARTx,u8 data)
{
	uint16 usart;
	if (USARTx == USART1) usart = 1;
	else if (USARTx == USART2) usart = 2; 
	else if (USARTx == USART3) usart = 3;
	else if (USARTx == UART4) usart = 4; 
	else usart = 5; 
	switch(usart) {
		case 1:
			FIFO_PUT_ONE(Uart1TxFifo,HexTAB[(data>>4)&0x0f]);
			FIFO_PUT_ONE(Uart1TxFifo,HexTAB[data&0x0f]);
			FIFO_PUT_ONE(Uart1TxFifo,' ');
			break;
		case 2:
			FIFO_PUT_ONE(Uart2TxFifo,HexTAB[(data>>4)&0x0f]);
			FIFO_PUT_ONE(Uart2TxFifo,HexTAB[data&0x0f]);
			FIFO_PUT_ONE(Uart2TxFifo,' ');
			break;
		case 3:
			FIFO_PUT_ONE(Uart3TxFifo,HexTAB[(data>>4)&0x0f]);
			FIFO_PUT_ONE(Uart3TxFifo,HexTAB[data&0x0f]);
			FIFO_PUT_ONE(Uart3TxFifo,' ');
			break;
		case 4:
			FIFO_PUT_ONE(Uart4TxFifo,HexTAB[(data>>4)&0x0f]);
			FIFO_PUT_ONE(Uart4TxFifo,HexTAB[data&0x0f]);
			FIFO_PUT_ONE(Uart4TxFifo,' ');
			break;
		case 5:
			FIFO_PUT_ONE(Uart5TxFifo,HexTAB[(data>>4)&0x0f]);
			FIFO_PUT_ONE(Uart5TxFifo,HexTAB[data&0x0f]);
			FIFO_PUT_ONE(Uart5TxFifo,' ');
			break;
	}
}

void USARTxSendNByteHex(USART_TypeDef *USARTx,u8 *pdata,uint16 len)
{
	uint16 i;
	for (i=0;i<len;i++)	{
		USARTxSendByteHex(USARTx,*pdata);
		pdata ++;
	}
}

void USARTxSendWordHex(USART_TypeDef *USARTx,u32 data)
{
	uint16 usart;
	if (USARTx == USART1) usart = 1;
	else if (USARTx == USART2) usart = 2; 
	else if (USARTx == USART3) usart = 3;
	else if (USARTx == UART4) usart = 4; 
	else usart = 5; 
	switch(usart) {
		case 1:
			FIFO_PUT_ONE(Uart1TxFifo,HexTAB[(data>>28)&0x0f]);
			FIFO_PUT_ONE(Uart1TxFifo,HexTAB[(data>>24)&0x0f]);
			FIFO_PUT_ONE(Uart1TxFifo,HexTAB[(data>>20)&0x0f]);
			FIFO_PUT_ONE(Uart1TxFifo,HexTAB[(data>>16)&0x0f]);
			FIFO_PUT_ONE(Uart1TxFifo,HexTAB[(data>>12)&0x0f]);
			FIFO_PUT_ONE(Uart1TxFifo,HexTAB[(data>>8)&0x0f]);
			FIFO_PUT_ONE(Uart1TxFifo,HexTAB[(data>>4)&0x0f]);
			FIFO_PUT_ONE(Uart1TxFifo,HexTAB[(data)&0x0f]);
			FIFO_PUT_ONE(Uart1TxFifo,' ');
			break;
		case 2:
			FIFO_PUT_ONE(Uart2TxFifo,HexTAB[(data>>28)&0x0f]);
			FIFO_PUT_ONE(Uart2TxFifo,HexTAB[(data>>24)&0x0f]);
			FIFO_PUT_ONE(Uart2TxFifo,HexTAB[(data>>20)&0x0f]);
			FIFO_PUT_ONE(Uart2TxFifo,HexTAB[(data>>16)&0x0f]);
			FIFO_PUT_ONE(Uart2TxFifo,HexTAB[(data>>12)&0x0f]);
			FIFO_PUT_ONE(Uart2TxFifo,HexTAB[(data>>8)&0x0f]);
			FIFO_PUT_ONE(Uart2TxFifo,HexTAB[(data>>4)&0x0f]);
			FIFO_PUT_ONE(Uart2TxFifo,HexTAB[(data)&0x0f]);
			FIFO_PUT_ONE(Uart2TxFifo,' ');
			break;
		case 3:
			FIFO_PUT_ONE(Uart3TxFifo,HexTAB[(data>>28)&0x0f]);
			FIFO_PUT_ONE(Uart3TxFifo,HexTAB[(data>>24)&0x0f]);
			FIFO_PUT_ONE(Uart3TxFifo,HexTAB[(data>>20)&0x0f]);
			FIFO_PUT_ONE(Uart3TxFifo,HexTAB[(data>>16)&0x0f]);
			FIFO_PUT_ONE(Uart3TxFifo,HexTAB[(data>>12)&0x0f]);
			FIFO_PUT_ONE(Uart3TxFifo,HexTAB[(data>>8)&0x0f]);
			FIFO_PUT_ONE(Uart3TxFifo,HexTAB[(data>>4)&0x0f]);
			FIFO_PUT_ONE(Uart3TxFifo,HexTAB[(data)&0x0f]);
			FIFO_PUT_ONE(Uart3TxFifo,' ');
			break;
		case 4:
			FIFO_PUT_ONE(Uart4TxFifo,HexTAB[(data>>28)&0x0f]);
			FIFO_PUT_ONE(Uart4TxFifo,HexTAB[(data>>24)&0x0f]);
			FIFO_PUT_ONE(Uart4TxFifo,HexTAB[(data>>20)&0x0f]);
			FIFO_PUT_ONE(Uart4TxFifo,HexTAB[(data>>16)&0x0f]);
			FIFO_PUT_ONE(Uart4TxFifo,HexTAB[(data>>12)&0x0f]);
			FIFO_PUT_ONE(Uart4TxFifo,HexTAB[(data>>8)&0x0f]);
			FIFO_PUT_ONE(Uart4TxFifo,HexTAB[(data>>4)&0x0f]);
			FIFO_PUT_ONE(Uart4TxFifo,HexTAB[(data)&0x0f]);
			FIFO_PUT_ONE(Uart4TxFifo,' ');
			break;
		case 5:
			FIFO_PUT_ONE(Uart5TxFifo,HexTAB[(data>>28)&0x0f]);
			FIFO_PUT_ONE(Uart5TxFifo,HexTAB[(data>>24)&0x0f]);
			FIFO_PUT_ONE(Uart5TxFifo,HexTAB[(data>>20)&0x0f]);
			FIFO_PUT_ONE(Uart5TxFifo,HexTAB[(data>>16)&0x0f]);
			FIFO_PUT_ONE(Uart5TxFifo,HexTAB[(data>>12)&0x0f]);
			FIFO_PUT_ONE(Uart5TxFifo,HexTAB[(data>>8)&0x0f]);
			FIFO_PUT_ONE(Uart5TxFifo,HexTAB[(data>>4)&0x0f]);
			FIFO_PUT_ONE(Uart5TxFifo,HexTAB[(data)&0x0f]);
			FIFO_PUT_ONE(Uart5TxFifo,' ');
			break;
	}
}

void USARTxSendNum(USART_TypeDef *USARTx,u32 data)
{
	u32 temp,div;
	uint8 firstRV = 0;
	uint16 usart;
	if (USARTx == USART1) usart = 1;
	else if (USARTx == USART2) usart = 2; 
	else if (USARTx == USART3) usart = 3;
	else if (USARTx == UART4) usart = 4; 
	else usart = 5; 
	div = 1000000000;
	while (div > 0) {
		temp = data / div;
		data -= temp * div;
		div /= 10;
		if (temp > 0 || firstRV > 0) {
			
			switch(usart) {
				case 1:
					FIFO_PUT_ONE(Uart1TxFifo,temp + '0');
					break;
				case 2:
					FIFO_PUT_ONE(Uart2TxFifo,temp + '0');
					break;
				case 3:
					FIFO_PUT_ONE(Uart3TxFifo,temp + '0');
					break;
				case 4:
					FIFO_PUT_ONE(Uart4TxFifo,temp + '0');
					break;
				case 5:
					FIFO_PUT_ONE(Uart5TxFifo,temp + '0');
					break;
			}
			firstRV ++;
		}
	}
	if (firstRV == 0) {
		switch(usart) {
			case 1:
				FIFO_PUT_ONE(Uart1TxFifo,'0');
				break;
			case 2:
				FIFO_PUT_ONE(Uart2TxFifo,'0');
				break;
			case 3:
				FIFO_PUT_ONE(Uart3TxFifo,'0');
				break;
			case 4:
				FIFO_PUT_ONE(Uart4TxFifo,'0');
				break;
			case 5:
				FIFO_PUT_ONE(Uart5TxFifo,'0');
				break;
		}
	}	
}
*/

